using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.IO;
using Newtonsoft.Json.Linq;
using System.Xml;
using System.Threading.Tasks;
using System.Text;

namespace Pay.Core {
	public static class JsonHelper {
        /// <summary>
        /// 字符串xml转对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static T ToXmlObject<T>(this string xml) {
            return XmlHelper.XmlDeserialize<T>(xml, Encoding.UTF8);
        }
        /// <summary>
        /// 对象转json，去除\r\n 空格多余字符并对中文字符进行转码。
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToEscapeNonAsciiJson(this object obj) {
            string jsonString = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { StringEscapeHandling = StringEscapeHandling.EscapeNonAscii });
            return jsonString;
        }

        public static T ToObject<T>(this string sJasonData) {
			JsonSerializerSettings jsonSs = new JsonSerializerSettings();
            var timeConverter = new IsoDateTimeConverter();
            timeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            jsonSs.Converters.Add(timeConverter);
          //  jsonSs.Converters.Add(new DataTableConverter());
            return JsonConvert.DeserializeObject<T>(sJasonData, jsonSs);
		}

		public static object ToObject(this string sJasonData, Type type) {
			JsonSerializerSettings jsonSs = new JsonSerializerSettings();
			var timeConverter = new IsoDateTimeConverter();
			timeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
			jsonSs.Converters.Add(timeConverter);
			//jsonSs.Converters.Add(new DataTableConverter());
			return JsonConvert.DeserializeObject(sJasonData, type, jsonSs);
		}

		/// <summary>
		/// 验证是否JSON
		/// </summary>
		/// <returns><c>true</c>, if json start was ised, <c>false</c> otherwise.</returns>
		/// <param name="json">Json.</param>
		public static bool IsJsonStart(this string json) {
			if (!string.IsNullOrEmpty(json)) {
				json = json.Trim('\r', '\n', ' ');
				if (json.Length > 1) {
					char s = json[0];
					char e = json[json.Length - 1];
					return (s == '{' && e == '}') || (s == '[' && e == ']');
				}
			}
			return false;
		}

		public static String ToJson<T>(this T obj, params string[] str) {
			JsonSerializerSettings jsonSs = new JsonSerializerSettings();
			var timeConverter = new IsoDateTimeConverter();
			timeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
			jsonSs.Converters.Add(timeConverter);
            //jsonSs.Converters.Add(new DataTableConverter());
            //jsonSs.Converters.Add(new JavaScriptDateTimeConverter());
            //jsonSs.Culture = System.Threading.Thread.CurrentThread.CurrentCulture;
            //jsonSs.DateFormatHandling = DateFormatHandling.IsoDateFormat;
            //jsonSs.DateTimeZoneHandling = DateTimeZoneHandling.Local;
            jsonSs.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            if (str != null && str.Length > 0) {
				jsonSs.ContractResolver = new LimitPropsContractResolver(str, false);
			}
			string json = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None, jsonSs);
			return json;
		}

		public static String ToJson<T>(this T obj, bool retain, params string[] str) {
			JsonSerializerSettings jsonSs = new JsonSerializerSettings();
			var timeConverter = new IsoDateTimeConverter();
			timeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
			jsonSs.Converters.Add(timeConverter);
			//jsonSs.Converters.Add(new DataTableConverter());
			//jsonSs.Converters.Add(new JavaScriptDateTimeConverter());
			//jsonSs.Culture = System.Threading.Thread.CurrentThread.CurrentCulture;
			//jsonSs.DateFormatHandling = DateFormatHandling.IsoDateFormat;
			//jsonSs.DateTimeZoneHandling = DateTimeZoneHandling.Local;
			if (str != null && str.Length > 0) {
				jsonSs.ContractResolver = new LimitPropsContractResolver(str, retain);
			}
			string json = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None, jsonSs);
			return json;
		}


		public static String ToJsonTime<T>(this T obj) {
			JsonSerializerSettings jsonSs = new JsonSerializerSettings();
			var timeConverter = new IsoDateTimeConverter();
			timeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
			jsonSs.Converters.Add(timeConverter);
			//jsonSs.Converters.Add(new DataTableConverter());
			string json = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None, jsonSs);
			return json;
		}
		/// <summary>
		/// 解析JSON数组生成对象实体集合
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
		/// <returns>对象实体集合</returns>
		public static List<T> DeserializeJsonToList<T>(string json) where T : class {
			JsonSerializer serializer = new JsonSerializer();
			StringReader sr = new StringReader(json);
			object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
			List<T> list = o as List<T>;
			return list;
		}

		public static T GetJsonValue<T>(this JObject val, string parameterName) {
			if (val.HasValues) return val.GetValue(parameterName).Value<T>();
			return default(T);
		}
		public static T GetJsonValue<T>(this Object obj, string parameterName) {
			var val = obj as JObject;
			if (val.HasValues) return val.GetValue(parameterName).Value<T>();
			return default(T);
		}

		public static T ToObjectByXml<T>(this string xml) {
			if (xml.Contains("requestUrl"))
				xml = xml.Replace("&", "&amp;");
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(xml);
			string jsonText = JsonConvert.SerializeXmlNode(doc);
			JToken jToken = JToken.Parse(jsonText);
			var str = jToken.Value<JObject>("HFBankData").ToString();
			return JsonConvert.DeserializeObject<T>(str);
		}

		public static T ToObject<T>(this XmlDocument doc) {
			string jsonText = JsonConvert.SerializeXmlNode(doc);
			JToken jToken = JToken.Parse(jsonText);
			var str = jToken.Value<JObject>("HFBankData").ToString();
			return JsonConvert.DeserializeObject<T>(str);
		}

		public static XmlDocument ToXml<T>(this T obj) {
			string json = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None);
			json = "{\"?xml\":{\"@version\":\"1.0\",\"@encoding\":\"UTF-8\"},\"HFBankData\":" + json + "}";
			XmlDocument doc = JsonConvert.DeserializeXmlNode(json);
			return doc;
		}
		/// <summary>
		/// 从XML字符串中反序列化对象
		/// </summary>
		/// <typeparam name="T">结果对象类型</param>
		/// <param name="s">包含对象的XML字符串</param>
		/// <param name="encoding">编码方式</param>
		/// <returns>反序列化得到的对象</returns>
		public static Message01 XmlDeserialize(string s, Encoding encoding) {
			if (string.IsNullOrEmpty(s))
				throw new ArgumentNullException("s");
			if (encoding == null)
				throw new ArgumentNullException("encoding");

			XmlDocument doc = new XmlDocument();
			doc.LoadXml(s.Trim());
			string jsonText = JsonConvert.SerializeXmlNode(doc);
			JToken jToken = JToken.Parse(jsonText);
			string message = jToken.Value<JObject>("Message").ToString();
			return JsonConvert.DeserializeObject<Message01>(message);
		}
	}

	public class Message01 {
		public Head Head { get; set; }
		public Response Response { get; set; }
	}
	public class Head {
		public string Status { get; set; }
		public string StatusDesc { get; set; }
	}
	public class Response {
		public string retCode { get; set; }
		public string retMsg { get; set; }
	}
}